<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script type="text/javascript">

      var obj = {
        arr: [12,35,35,46],
        str: {name: "张三"}
      }

      // ES5 深拷贝
      function cleep1(origin, target) {
        var tar = target || {},
            str = '[object Object]',
            tostring = Object.prototype.toString;
        for(var k in origin) {
          if(origin.hasOwnProperty(k)) {
            if(typeof origin[k] === 'object' && origin !== null) {
              tar[k] = tostring.call(origin[k]) === str ? {} : [];
              cleep1(origin[k], tar[k]);
            } else {
              tar[k] = origin[k];
            } 
          }
        }
        return tar;
      }

      // ES6 深拷贝
      function cleep2 (origin) {
        if(origin == undefined || typeof origin !== 'object') {
          return origin;
        }

        if(origin instanceof Date) {
          return Date(origin);
        }

        if(origin instanceof RegExp) {
          return RegExp(origin);
        }

        if(origin instanceof Map) {
          return Map(origin);
        }

        var tar = origin.constructor();
        for(var k in origin) {
          tar[k] = cleep2(origin[k])
        }

        return tar;
      }

      var newObj = cleep2(obj);
      newObj.str.name = "李四";
      console.log(obj, newObj);


      var arr = [1, 12, 34, 56, 4, 57]

      Array.prototype.myfromEach = function (cb) {
        var _arr = this,
          _len = _arr.length,
          _arg2 = arguments[1] || window
        for (var i = 0; i < _len; i++) {
          cb.apply(_arg2, [_arr[i], i, _arr])
        }
      }

      arr.myfromEach(function (item, index, arr) {
        console.log(item, index, arr, this)
      }, arr)


      Array.prototype.myMap = function(cb) {
        var _arr = this,
            len = _arr.length,
            arg2 = arguments[1] || window,
            newArr = [];
        for(var i = 0; i < len; i++) {
          cb.apply(arg2, [_arr[i], i, _arr]) && newArr.push(cb.apply(arg2, [_arr[i], i, _arr]))
        }
        return newArr;
      }

      console.log(arr.myMap(function(item, index) {
        if(item > 12) {
          return item;
        }
      }))

      Array.prototype.myFilter = function(cb) {
        var _arr = this,
            _len = _arr.length,
            _arg2 = arguments[1] || window,
            _newarr = [],
            item;
        for(var i = 0; i < _len; i++) {
          item = cleep2(_arr[i])
          cb.apply(_arg2, [item, i, _arr]) ? _newarr.push(item) : '';
        }

        return _newarr;
      }
      console.log("myfilter", arr.myFilter((item) => item > 4));
      
      Array.prototype.myEvery = function(cb) {
        var _arr = this,
            _len = _arr.length,
            _arg2 = arguments[1] || window,
            item = true;
        for(var i = 0; i < _len; i++) {
          if(!cb.apply(_arg2, [_arr[i], i, _arr])) {
            item = false;
            break;
          }
        }
        return item;
      }
      console.log(arr.myEvery(item => item < 10));


      Array.prototype.mySome = function (cb) {
        var _arr = this,
            _len = _arr.length,
            _arg2 = arguments[1] || window,
            item = false;
        for(var i = 0; i < _len; i++) {
          if(cb.call(_arg2, _arr[i], i, _arr)){
            return true;
          }
        }
        return item;
      }
      console.log(arr.mySome(item => item <= 1));


      // 正向累加器 
      Array.prototype.myReduce = function(cb, initalValue) {
        var _arr = this,
            _len = _arr.length,
            _arg3 = arguments[2] || window,
            _item;
        for(var i = 0; i < _len; i++) {
          _item = cleep2(_arr[i])
          initalValue = cb.apply(_arg3, [initalValue, _item, i, _arr]);
        } 
        return initalValue;
      }
      var initval = 0
      initval = arr.myReduce(function(initval, item){
        return initval += item;
      }, initval)
      console.log(initval)

      // 方向累加器 
      Array.prototype.myReduceRight = function(cb, initalValue) {
        var _arr = this,
            _len = _arr.length,
            _arg3 = arguments[2] || window,
            _item;

        for(var i = _len - 1; i >= 0; i--) {
          _item = cleep2(_arr[i]);
          initalValue = cb.apply(_arg3, [initalValue, _item, i, _arr]);
        } 
        return initalValue;
      }
      console.log(arr.myReduceRight(function(initval, item, index){
        return initval + item;
      }, 0))

    </script>
  </body>
</html>
